vt-d: Better restrict memory ranges considered to be in Xen
authorKeir Fraser <keir.fraser@citrix.com>
Fri, 6 Mar 2009 19:06:30 +0000 (19:06 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Fri, 6 Mar 2009 19:06:30 +0000 (19:06 +0000)
The current implementation of xen_in_range() misses several memory
ranges that are used by the hypervisor and thus shouldn't get mapped
into dom0's VT-d tables.  This patch should make the check complete.

This patch is only against x86 because I'm not familiar enough with
IA64 to know how much, if any, of these checks apply there.

Signed-off-by: Joseph Cihula <joseph.cihula@intel.com>
xen/arch/x86/setup.c

index 8b9427878ed94a8be34a9feb2c30ab10a141e321..2fe4b375f90aac1dd336a51681b6f70bb660f85e 100644 (file)
@@ -1111,15 +1111,43 @@ void arch_get_xen_caps(xen_capabilities_info_t *info)
 
 int xen_in_range(paddr_t start, paddr_t end)
 {
-#if defined(CONFIG_X86_32)
-    paddr_t xs = 0;
-    paddr_t xe = xenheap_phys_end;
-#else
-    paddr_t xs = __pa(&_stext);
-    paddr_t xe = __pa(&_etext);
-#endif
+    int i;
+    static struct {
+        paddr_t s, e;
+    } xen_regions[5];
+
+    /* initialize first time */
+    if ( !xen_regions[0].s )
+    {
+        extern char __init_begin[], __per_cpu_start[], __per_cpu_end[],
+                    __bss_start[];
+        extern unsigned long allocator_bitmap_end;
+
+        /* S3 resume code (and other real mode trampoline code) */
+        xen_regions[0].s = bootsym_phys(trampoline_start);
+        xen_regions[0].e = bootsym_phys(trampoline_end);
+        /* hypervisor code + data */
+        xen_regions[1].s =__pa(&_stext);
+        xen_regions[1].e = __pa(&__init_begin);
+        /* per-cpu data */
+        xen_regions[2].s = __pa(&__per_cpu_start);
+        xen_regions[2].e = __pa(&__per_cpu_end);
+        /* bss + boot allocator bitmap */
+        xen_regions[3].s = __pa(&__bss_start);
+        xen_regions[3].e = allocator_bitmap_end;
+        /* frametable */
+        xen_regions[4].s = (unsigned long)frame_table;
+        xen_regions[4].e = (unsigned long)frame_table +
+                           PFN_UP(max_page * sizeof(*frame_table));
+    }
+
+    for ( i = 0; i < ARRAY_SIZE(xen_regions); i++ )
+    {
+        if ( (start < xen_regions[i].e) && (end > xen_regions[i].s) )
+            return 1;
+    }
 
-    return (start < xe) && (end > xs);
+    return 0;
 }
 
 /*